package com.ttc.mBackup.BackupContacts;

import java.util.ArrayList;


import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;

public class ContactDAO {

	private Cursor cursor;
	private ContentResolver contentResolver;

	public ContactDAO() {
		super();

	}

	public ContactDAO(ContentResolver contentResolver) {
		super();
		this.contentResolver = contentResolver;
		this.cursor=contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
	}

	public ContentResolver getContentResolver() {
		return contentResolver;
	}

	public void setContentResolver(ContentResolver contentResolver) {
		this.contentResolver = contentResolver;
		this.cursor=contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
	}

	public ArrayList<Contact>readAllContacts(){
		ArrayList<Contact>contacts=new ArrayList<Contact>();
		
		String id;
		if(this.cursor.getCount()>0){
			int i=0;
			while(i<cursor.getCount()){
				if(cursor.moveToPosition(i)){
					Contact contact=new Contact();
					id=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
					contact.set_id(id);
					contact.setAddresses(getAddresses(id));
					contact.setEmails(getEmails(id));
					contact.setIms(getIms(id));
					contact.setOrganizations(getOrganizations(id));
					contact.setPhones(getPhoneNumbers(id));
					contact.setStructuredName(getStructuredName(id));
					
					contacts.add(contact);
					i++;
				}
			}
		}
		return contacts;
		
	}
	
	private ArrayList<Phone>getPhoneNumbers(String contactID){
		ArrayList<Phone>phones=new ArrayList<Phone>();
		String where=ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?";
		String[]args=new String[]{contactID};
		Cursor mCursor=contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, where, args, null);
		Log.i("phone count", "" + mCursor.getCount());
		int i=0;
		while(i<mCursor.getCount()){
			if(mCursor.moveToPosition(i)){
				Phone phone=new Phone();
				phone.setNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
				phone.setType(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)));
				phones.add(phone);
				i++;
			}else {
					Log.e("ERROR at method getEmails", "cause: cannot move cursor to position " + i, new Exception("cursor move exception"));
					
				}
		}
		mCursor.close();
		return phones;
	}
	
	private ArrayList<Address>getAddresses(String contactID){
		ArrayList<Address>addresses=new ArrayList<Address>();
		String where=ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "= ?";
		String[]args=new String[]{contactID};
		Cursor mCursor=contentResolver.query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI, null, where, args, null);
		Log.i("address count", "" + mCursor.getCount());
		for(int i=0;i<mCursor.getCount();i++){
			if(mCursor.moveToPosition(i)){
				Address address=new Address();
				address.setCity(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY)));
				address.setCountry(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY)));
				address.setNeighborhood(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.NEIGHBORHOOD)));
				address.setPoBox(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POBOX)));
				address.setState(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION)));
				address.setStreet(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET)));
				address.setType(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE)));
				address.setZipCode(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE)));
				addresses.add(address);
			}else {
				Log.e("ERROR at method getAddress", "cause: cannot move cursor to position " + i, new Exception("cursor move exception"));
				
			}
		}
		mCursor.close();
		return addresses;
	}
	
	private ArrayList<Email>getEmails(String contactID){
		ArrayList<Email>emails=new ArrayList<Email>();
		String where=ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "= ?";
		String[]args=new String[]{contactID};
		Cursor mCursor=contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, where, args, null);
		Log.i("email count", "" + mCursor.getCount());
	
		for(int i=0;i<mCursor.getCount();i++){
			if(mCursor.moveToPosition(i)){
				Email email=new Email();
				email.setEmail(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)));
				email.setType(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE)));
				emails.add(email);
				
			}else {
				Log.e("ERROR at method getEmails", "cause: cannot move cursor to position " + i, new Exception("cursor move exception"));
				
			}
	}
	mCursor.close();
	return emails;
}
	
	private ArrayList<IM>getIms(String contactID){
		ArrayList<IM>ims=new ArrayList<IM>();
		String where = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE +" =?";
		String[] args = new String[] { contactID, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE  };
		Cursor mCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, null, where, args, null);
		Log.i("im count", "" + mCursor.getCount());
		for(int i=0;i<mCursor.getCount();i++){
			if(mCursor.moveToPosition(i)){
				IM im=new IM();
				im.setIm(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)));
				im.setType(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.TYPE)));
				ims.add(im);
			}else {
				Log.e("ERROR at method getims", "cause: cannot move cursor to position " + i, new Exception("cursor move exception"));
				
			}
		}
		mCursor.close();
		return ims;
	}
	
	private ArrayList<Organization>getOrganizations(String contactID){
		ArrayList<Organization>orgs=new ArrayList<Organization>();
		String where =ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE +"=?";
		String[] args=new String[]{contactID, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE};
		Cursor mCursor=contentResolver.query(ContactsContract.Data.CONTENT_URI, null, where, args, null);
		Log.i("organization count", ""+mCursor.getCount());
		for(int i=0;i<mCursor.getCount();i++){
			if(mCursor.moveToPosition(i)){
				Organization org=new Organization();
				org.setCompany(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.DATA)));
				org.settitle(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE)));
				org.setType(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TYPE)));
				orgs.add(org);
			}else{
				Log.e("ERROR at method getOrganization", "cause: cannot move cursor to position "+ i, new Exception("cursor move exception"));
			}
		}
		mCursor.close();
		return orgs;
	}
	
	private StructuredName getStructuredName(String contactID){
		StructuredName structuredName=new StructuredName();
		String where=ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID +"=?";
		String[] args=new String[]{contactID};
		Cursor mCursor=contentResolver.query(ContactsContract.Data.CONTENT_URI, null, where, args, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
		while(mCursor.moveToNext()){
			String display=mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
			String family=mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
			String given=mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
			String middle=mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
			String phoneticFamily=mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_FAMILY_NAME));
			String phoneticGiven=mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_GIVEN_NAME));
			String phoneticMiddle=mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_MIDDLE_NAME));
			String prefix=mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.PREFIX));
			String suffix=mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.SUFFIX));
			
			structuredName.setDisplayName(display);
			structuredName.setFamilyName(family);
			structuredName.setGivenName(given);
			structuredName.setMiddleName(middle);
			structuredName.setNamePrefix(prefix);
			structuredName.setNameSuffix(suffix);
			structuredName.setPhoneticFamilyName(phoneticFamily);
			structuredName.setPhoneticGivenName(phoneticGiven);
			structuredName.setPhoneticMiddleName(phoneticMiddle);
		}
		return structuredName;
	}
	
	public void writeContact(Contact contact){
		if(contact==null) return;
		ContentValues values = new ContentValues();
		values.put(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, "Leo Messi");
		Uri rawContactUri=contentResolver.insert(RawContacts.CONTENT_URI, values);
		long rawContactId = ContentUris.parseId(rawContactUri);
		
		values.clear();
		values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
		Uri strnameUri=null;
		Uri phoneUri = null;
		Uri emailUri = null;
		Uri noteUri=null;
		Uri addressUri = null;
		Uri imUri = null;
		Uri orgUri = null;
		
		if(contact.getStructuredName()!=null){
			Log.i("DisplayName", "" + contact.getStructuredName().getDisplayName());
			strnameUri=Uri.withAppendedPath(rawContactUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
			values.clear();
			values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
			values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contact.getStructuredName().getDisplayName());
			values.put(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, contact.getStructuredName().getFamilyName());
			values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getStructuredName().getGivenName());
			values.put(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME, contact.getStructuredName().getMiddleName());
			values.put(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_FAMILY_NAME, contact.getStructuredName().getPhoneticFamilyName());
			values.put(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_MIDDLE_NAME, contact.getStructuredName().getPhoneticMiddleName());
			values.put(ContactsContract.CommonDataKinds.StructuredName.PHONETIC_GIVEN_NAME, contact.getStructuredName().getPhoneticGivenName());
			contentResolver.insert(strnameUri, values);
		}
		
		if (contact.getPhones() != null) {
			Log.i("Phone size", "" + contact.getPhones().size());
			for (Phone aPhone : contact.getPhones()) {
				phoneUri = Uri.withAppendedPath(rawContactUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
				values.clear();
				values.put(ContactsContract.CommonDataKinds.Phone.TYPE, aPhone.getType());
				values.put(ContactsContract.CommonDataKinds.Phone.IS_SUPER_PRIMARY, 1);
				values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
				values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, aPhone.getNumber());
				contentResolver.insert(phoneUri, values);
			}
		}
		
		if(contact.getEmails()!=null){
			Log.i("Email", "" + contact.getEmails().size());
			for(Email aEmail:contact.getEmails()){
				emailUri=Uri.withAppendedPath(rawContactUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
				values.clear();
				values.put(ContactsContract.CommonDataKinds.Email.TYPE, aEmail.getType());
				values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE);
				values.put(ContactsContract.CommonDataKinds.Email.DATA, aEmail.getEmail());
				contentResolver.insert(emailUri, values);
			}
		}
		
		if(contact.getNotes()!=null){
			Log.i("Notes size", ""+contact.getNotes().size());
			for(String aNote:contact.getNotes()){
				noteUri=Uri.withAppendedPath(rawContactUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
				values.clear();
				values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE);
				values.put(ContactsContract.CommonDataKinds.Note.NOTE, aNote);
				contentResolver.insert(noteUri, values);
			}
		}
		
		if (contact.getIms() != null) {
			Log.i("IM size", "" + contact.getIms().size());
			for (IM aIM : contact.getIms()) {
				imUri = Uri.withAppendedPath(rawContactUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
				values.clear();
				values.put(ContactsContract.CommonDataKinds.Im.PROTOCOL, aIM.getType());
				values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE);
				values.put(ContactsContract.CommonDataKinds.Im.DATA, aIM.getIm());
				contentResolver.insert(imUri, values);
			}
		}
		
		if(contact.getAddresses()!=null){
			Log.i("Address size", "" + contact.getAddresses().size());
				for (Address aAdd : contact.getAddresses()) {
					addressUri = Uri.withAppendedPath(rawContactUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
					values.clear();
					values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE);
					if (aAdd.getCity() != null)
						values.put(ContactsContract.CommonDataKinds.StructuredPostal.CITY, aAdd.getCity());
					if (aAdd.getCountry() != null)
						values.put(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, aAdd.getCountry());
					if (aAdd.getPoBox() != null)
						values.put(ContactsContract.CommonDataKinds.StructuredPostal.POBOX, aAdd.getPoBox());
					if (aAdd.getNeighborhood() != null)
						values.put(ContactsContract.CommonDataKinds.StructuredPostal.NEIGHBORHOOD, aAdd.getNeighborhood());
					if (aAdd.getStreet() != null)
						values.put(ContactsContract.CommonDataKinds.StructuredPostal.STREET, aAdd.getStreet());
					if (aAdd.getState() != null)
						values.put(ContactsContract.CommonDataKinds.StructuredPostal.REGION, aAdd.getState());
					if(aAdd.getZipCode()!=null)
						values.put(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE, aAdd.getZipCode());
										
					values.put(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, aAdd.getType());
					contentResolver.insert(addressUri, values);
				}
		}
		
		if (contact.getOrganizations() != null) {
			Log.i("Org size", "" + contact.getOrganizations().size());
			for (Organization aORG : contact.getOrganizations()) {
				orgUri = Uri.withAppendedPath(rawContactUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
				values.clear();
				values.put(ContactsContract.CommonDataKinds.Organization.TYPE, aORG.getType());
				values.put(ContactsContract.CommonDataKinds.Organization.TITLE, aORG.gettitle());// TODO:
				// check
				// again
				values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE);
			 	values.put(ContactsContract.CommonDataKinds.Organization.DATA, aORG.getCompany());
				contentResolver.insert(orgUri, values);
			}
		}
	}
	public boolean writeContact(ArrayList<Contact> contacts) {
			try {
				for (Contact aContact : contacts) {
					writeContact(aContact);
				}
				return true;
			} catch (Exception ex) {
				ex.printStackTrace();// show error in DDMS
				return false;
			}
		}
		
	}
